第19天是網頁使用視訊鏡頭來抓取視訊畫面,讓視訊畫面呈現在網頁上,並可以加入畫面特效,還可將網頁影像轉換成影像檔案。
首先畫面開啟錄影鏡頭功能,使用navigator.mediaDevices.getUserMedia
來開啟鏡頭功能,並取得鏡頭錄製畫面的影像,將影像透過video
元素播放。
function getVideo() {
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then( localMediaStream =>{
video.src = window.URL.createObjectURL(localMediaStream)
video.play()
})
.catch(err =>{
console.error('Error', err)
})
}
之後將影像畫面結果畫上canvas
元素,使用ctx.getImageData()
來讓video的影像資料畫到canvas
上,透過setInterval()
讓其固定秒數觸發繪畫到canvas
元素。設定為16毫秒就重新繪畫一次。
function paintToCanvas() {
const width = video.videoWidth
const height = video.videoHeight
canvas.width = width
canvas.height = height
return setInterval(()=>{
ctx.drawImage(video, 0, 0, width, height)
let pixels = ctx.getImageData(0, 0, width, height)
pixels.data = mirror(pixels, width, height)
// 讓畫面產生產生鏡像畫面
pixels = redEffect(pixels)
// pixels值 紅色調大
pixels = rgbSplit(pixels)
ctx.globalAlpha = 0.1
// 顏色 位置對調
pixels = greenScreen(pixels)
//
ctx.putImageData(pixels, 0, 0);
}, 16)
在畫到canvas
的過程中,可以透過ctx.getImageData()
的方式來取得canvas
上的像素值,每一個像素值共有四個值為(RGBA),之後可對取得的像素值做特定的效果變化。
之後製作類似拍照的功能,首先建立一個click
事件,在click
事件中包含事件觸發時產生拍攝的音效,以及將canvas
中的資料成點陣圖的連結,將連結轉換成a
元素,並a
元素插入到strip
元素的第一個子元素之前。
function takePhoto(){
// palyed the sound
snap.currentTime=0
snap.play()
// take data out of canvas
const data = canvas.toDataURL('image/jpeg', 1.0)
const link = document.createElement('a')
link.href = data
link.setAttribute('Download', 'doenloadName')
link.innerHTML=`<img src=${data} alt='canvase ' >`
strip.insertBefore(link, strip.firstChild)
}
這樣就可以完成攝影鏡頭的實作,包含畫面特效和轉換成圖片檔案。
<canvas class="photoCan"></canvas>
<video class="playerCam"></video>
<audio class="snapAud" src="http://wesbos.com/demos/photobooth/snap.mp3" hidden></audio>
navigator
The Navigator interface represents the state and the identity of the user agent. It allows scripts to query it and to register themselves to carry on some activities.
MediaDevicesNavigator.mediaDevices
提供連結到影音輸入裝置,例如鏡頭和麥克風。
MediaDevices.getUserMedia()MediaDevices.getUserMedia()
方法允使用者使用媒體裝置產生MediaStream
的內容。
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
/* use the stream */
})
.catch(function(err) {
/* handle the error */
});
URL.createObjectURL()
用於建立一個帶有URL的 DOMString 以代表參數中所傳入的物件.bjectURL = URL.createObjectURL(object);
drawImage()
方法提供Canvas
能夠畫上image
。var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var image = document.getElementById('source');
ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
CanvasRenderingContext2D.putImageData()putImageData()
方法將canvas
的資料轉換成點陣圖bitmap
。
The CanvasRenderingContext2D.putImageData() method of the Canvas 2D API paints data from the given ImageData object onto the bitmap.
HTMLCanvasElement.toDataURL()URL.createObjectURL()
用於建立一個帶有URL的 DOMString 以代表參數中所傳入的物件. 該URL的生命週期與創造它的window中的 document一致. 這個新的物件URL 代表了所指定的 File 物件 或是 Blob 物件.toDataURL()
方法是回傳代表影像格式資料的
The HTMLCanvasElement.toDataURL() method returns a data URI containing a representation of the image in the format specified by the type parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.
var fullQuality = canvas.toDataURL('image/jpeg', 1.0);
// data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...9oADAMBAAIRAxEAPwD/AD/6AP/Z"
var mediumQuality = canvas.toDataURL('image/jpeg', 0.5);
var lowQuality = canvas.toDataURL('image/jpeg', 0.1);
insertBefore()
在特定元素中插入元素。var sp1 = document.createElement("span");
var sp2 = document.getElementById("childElement");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(sp1, sp2); // 插入sp1 至 sp2 之前
video
, canvas
, navigator